package com.bblocks.common;

import com.bblocks.enums.SysEnum;
import com.bblocks.exception.ServiceException;
import com.bblocks.util.R;
import lombok.extern.slf4j.Slf4j;

import org.springframework.dao.DuplicateKeyException;
import org.springframework.dao.NonTransientDataAccessException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MultipartException;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

/**
 * @Author: Mei
 * @Date: created in 2018/12/27 11:39.
 */
@Slf4j
@RestControllerAdvice
public class ControllerException {
	
    //声明要捕获的异常
    @ExceptionHandler(Exception.class)
    public R defaultExceptionHandler(Exception e, HttpServletRequest request) {
    	log.error("异常请求url>>>>>=====:" + request.getRequestURL());
        if (e instanceof ServiceException) {
            log.error("业务异常>>>>>=====:" + e.getMessage());
            ServiceException serviceException = (ServiceException) e;
            return R.failed(serviceException.getCode(), serviceException.getMessage());
        }
        if (e instanceof IllegalArgumentException) {
            log.error("参数校验失败>>>>>=====:" + e.getMessage());

            return R.failed(SysEnum.PARAMS_IS_INVALID.getCode(), e.getMessage());
        }

		if(e instanceof MethodArgumentNotValidException){


			BindingResult result = ((MethodArgumentNotValidException)e).getBindingResult();
			StringBuilder message = new StringBuilder();
			//Map<String,String> message = new HashMap();
			if (result.hasErrors()) {
				List<ObjectError> errors = result.getAllErrors();
				if (errors != null) {
					errors.forEach(p -> {
						FieldError fieldError = (FieldError) p;
						log.info("Data check failure : object{" + fieldError.getObjectName() + "},field{" + fieldError.getField() +
								"},errorMessage{" + fieldError.getDefaultMessage() + "}");

						//message.append("字段:"+fieldError.getObjectName()+" "+fieldError.getDefaultMessage());
						//message.put(fieldError.getObjectName(),fieldError.getDefaultMessage());
						if(message.length() ==0)
							message.append(fieldError.getDefaultMessage());
						else
							message.append(","+fieldError.getDefaultMessage());
					});
					//if (errors.size() > 0) {
					//	FieldError fieldError = (FieldError) errors.get(0);
					//message = fieldError.getDefaultMessage();
					//}
				}
			}
			log.info("参数校验失败>>>>>=====:" + message);
			//return Message.fail("".equals(message) ? "请填写正确信息" : message);

			return R.sysError(SysEnum.PARAMS_IS_INVALID, "参数校验失败:"+message.toString());
		}

        if (e instanceof DuplicateKeyException) {
        	log.error("数据库的完整性约束异常>>>>>=====:" + e.getMessage(), e);
            return R.failed(SysEnum.DATA_ALREADY_EXISTED.getCode(), e.getMessage());
		}
        if(e instanceof NonTransientDataAccessException){
            log.error("数据操作异常>>>>>=====:" + e.getMessage(), e);
            return R.failed(SysEnum.DATA_VIOLATION.getCode(), "不要传undefined等...参数请符合逻辑");
        }
        if(e instanceof MultipartException){
        	log.error("上传异常>>>>>=====:" + e.getMessage(), e);
            return R.failed(SysEnum.UPLOAD_ERROR.getCode(), "文件太大了，重新上传！");
        }
        if(e instanceof NumberFormatException){
            log.error("前端参数异常>>>>>=====:" + e.getMessage(), e);
            return R.failed(SysEnum.PARAMS_TYPE_ERROR.getCode(), e.getMessage());
        }
        //if (e instanceof ClientAbortException) {
        //	log.error("客户端端主动关闭请求异常>>>>>=====:" + e.getMessage());
        //    return new Result(SysEnum.ERROR, e.getMessage());
		//}
        log.error("未知异常>>>>>=====:" + e.getMessage(), e);
        return R.failed(SysEnum.UNKNOWN_ERROR.getCode(), e.getMessage());
    }



    
    /**
     * 	解决前端参数undefined报错问题
     * @param binder

    @InitBinder
    public void dataBind(WebDataBinder binder) {
        ///給指定类型注册类型转换器操作
    	binder.registerCustomEditor(Byte.class, new PropertyEditor<Byte>(Byte.class));
    	binder.registerCustomEditor(Integer.class, new PropertyEditor<Integer>(Integer.class));
        binder.registerCustomEditor(Boolean.class, new PropertyEditor<Boolean>(Boolean.class));
    } */
}
